ESP32双核CPU,利用核0实现蓝牙打印机打印,核1完成常规控制

您所在的位置:网站首页 esp32 打印机改无线 ESP32双核CPU,利用核0实现蓝牙打印机打印,核1完成常规控制

ESP32双核CPU,利用核0实现蓝牙打印机打印,核1完成常规控制

2024-07-09 12:47| 来源: 网络整理| 查看: 265

ESP32双核CPU,利用核0实现蓝牙打印机打印,核1完成常规控制 目的程序编制总结

目的

开发一个仪表,在使用过程中发现用ESP32控制打印机和主控制有冲突,会造成数据采集流程慢。而控制蓝牙打印的过程需要回调函数,速度比较慢,考虑到ESP32具有两个核,实际上我们用Arduino进行编程时只使用到了第一个核,第0核并没有使用。想到将0核利用起来,这个核只控制BLE蓝牙打印机,带着这个想法开始试验。

程序编制

下面不说废话,进入编程。用Arduino自带的例子进行编程。

首先是要在程序程序中引用库:

#include "BLEDevice.h"

头文件的详细介绍这里就不展开了。

下面是定义要使用蓝牙打印机的两个参数:

// The remote service we wish to connect to. static BLEUUID serviceUUID("000018f0-0000-1000-8000-00805f9b34fb"); // The characteristic of the remote service we are interested in. static BLEUUID charUUID("00002af1-0000-1000-8000-00805f9b34fb");

这两个参数是使用打印机的关键,一个是服务的标识,一个是服务的特性标识。这两个参数是我用一个免费的手机软件读取的,软件的名字叫“BLE调试宝”。在华为的商店里可以找到,下载,然后查找打印机的服务,也可以在这个软件上向打印机发送ASCII打印数据。如果有问题,可以另文介绍。也可以参见我的另一篇文章ESP32蓝牙打印机.

定义所有的静态变量:

// The remote service we wish to connect to. static bool doConnect = false; // 连接 static bool connected = false; // 已经连接 static bool doScan = false; // 扫描 static BLERemoteCharacteristic* pRemoteCharacteristic; static BLEAdvertisedDevice* myDevice; bool bBLEConnect = false; bool bBLEPrinter = false; // 定义Notify的回调函数,这个函数在我们的程序中不使用 static void notifyCallback( BLERemoteCharacteristic* pBLERemoteCharacteristic, uint8_t* pData, size_t length, bool isNotify) { Serial.print("Notify callback for characteristic "); Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str()); Serial.print(" of data length "); Serial.println(length); Serial.print("data: "); Serial.println((char*)pData); } // 定义回调的类,class class MyClientCallback : public BLEClientCallbacks { void onConnect(BLEClient* pclient) { // 连接时可以添加代码,比如连接了打印机可以打印回车 } void onDisconnect(BLEClient* pclient) { connected = false; Serial.println("onDisconnect"); } }; // 连接 Server 的分程序,当发现自己要连接的ServerUUID和CharacteristicUUID时执行 bool connectToServer() { Serial.print("Forming a connection to "); Serial.println(myDevice->getAddress().toString().c_str()); BLEClient* pClient = BLEDevice::createClient(); Serial.println(" - Created client"); pClient->setClientCallbacks(new MyClientCallback()); // Connect to the remove BLE Server. pClient->connect(myDevice); // if you pass BLEAdvertisedDevice instead of address, //it will be recognized type of peer device address (public or private) Serial.println(" - Connected to server"); // Obtain a reference to the service we are after in the remote BLE server. BLERemoteService* pRemoteService = pClient->getService(serviceUUID); if (pRemoteService == nullptr) { Serial.print("Failed to find our service UUID: "); Serial.println(serviceUUID.toString().c_str()); pClient->disconnect(); return false; } Serial.println(" - Found our service"); // Obtain a reference to the characteristic in the service of the remote BLE server. pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID); if (pRemoteCharacteristic == nullptr) { Serial.print("Failed to find our characteristic UUID: "); Serial.println(charUUID.toString().c_str()); pClient->disconnect(); return false; } Serial.println(" - Found our characteristic"); // Read the value of the characteristic. if(pRemoteCharacteristic->canRead()) { std::string value = pRemoteCharacteristic->readValue(); Serial.print("The characteristic value was: "); Serial.println(value.c_str()); } if(pRemoteCharacteristic->canNotify()) pRemoteCharacteristic->registerForNotify(notifyCallback); connected = true; return true; } // 定义发现蓝牙设备的类 class /** * Scan for BLE servers and find the first one that advertises the service we are looking for. */ class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks { /** * Called for each advertising BLE server. */ void onResult(BLEAdvertisedDevice advertisedDevice) { Serial.print("BLE Advertised Device found: "); Serial.println(advertisedDevice.toString().c_str()); // We have found a device, let us now see if it contains the service we are looking for. if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) { BLEDevice::getScan()->stop(); myDevice = new BLEAdvertisedDevice(advertisedDevice); doConnect = true; doScan = true; } // Found our server } // onResult }; // MyAdvertisedDeviceCallbacks // 定义三个指示灯,这个根据板子定义 /* 指示灯变量 */ const byte RLED = 14; // run led const byte DSEND = 12; // send led const byte DRECV = 13; // receive led /* --------------------------------------------------------------*/ uint32_t xCnt01 = 0; // setup()函数,这个函数是在核1中执行的。可以在这里定义要运行核0的函数 void setup() { Serial.begin(115200); Serial.println("Starting Arduino BLE Client application..."); pinMode(RLED, OUTPUT); pinMode(DSEND, OUTPUT); pinMode(DRECV, OUTPUT); digitalWrite(RLED, HIGH); digitalWrite(DSEND, HIGH); digitalWrite(DRECV, HIGH); Serial.printf("ESP32 chip revision : %d\r\n", (int16_t)ESP.getChipRevision()); Serial.printf("ESP32 SDK Version : %s\r\n", ESP.getSdkVersion()); Serial.printf("ESP32 Speed : %u MHz\r\n", ESP.getCpuFreqMHz()); Serial.print("Task ReadMMeter function running on core: "); Serial.println(xPortGetCoreID()); xTaskCreatePinnedToCore( TaskPBle , "BLEPriter" // A name just for humans , 1024 * 10 // This stack size can be checked & adjusted by reading the Stack Highwater , NULL , 1 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest. , NULL , 0); // 这个0,表示要执行的TaskPBle是在核0中执行。 } // End of setup. // 核1 执行的程序,做了一个闪亮的指示灯 // This is the Arduino main loop function. void loop() { xCnt01++; if (xCnt01 > 2880000) { xCnt01 = 0; digitalWrite(RLED, !digitalRead(RLED)); } // delay(1000); // Delay a second between loops. } // End of loop // 核 0 的程序,蓝牙打印机打印。 void TaskPBle(void *pvParameters) { (void) pvParameters; Serial.print("Task2 running on core "); Serial.println(xPortGetCoreID()); Serial.println("Starting Arduino BLE Client application..."); BLEDevice::init(""); // Retrieve a Scanner and set the callback we want to use to be informed when we // have detected a new device. Specify that we want active scanning and start the // scan to run for 5 seconds. BLEScan* pBLEScan = BLEDevice::getScan(); pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); pBLEScan->setInterval(1349); pBLEScan->setWindow(449); pBLEScan->setActiveScan(true); pBLEScan->start(10, false); for (;;) { // If the flag "doConnect" is true then we have scanned for and found the desired // BLE Server with which we wish to connect. Now we connect to it. Once we are // connected we set the connected flag to be true. if (doConnect == true) { if (connectToServer()) { Serial.println("We are now connected to the BLE Server."); } else { Serial.println("We have failed to connect to the server; there is nothin more we will do."); } doConnect = false; } // If we are connected to a peer BLE Server, update the characteristic each time we are reached // with the current time since boot. if (connected) { if ( Serial.available()) { Serial.readString(); String xStr = "----- Test Report -----\r\n"; Serial.println(xStr); pRemoteCharacteristic->writeValue(xStr.c_str(), xStr.length()); xStr = "Date:2020-5-30\r\n"; pRemoteCharacteristic->writeValue(xStr.c_str(), xStr.length()); xStr = "Time:19:18:30\r\n"; pRemoteCharacteristic->writeValue(xStr.c_str(), xStr.length()); xStr = "Max: 3.69 mm\r\n"; pRemoteCharacteristic->writeValue(xStr.c_str(), xStr.length()); xStr = "Min: 1.69 mm\r\n"; pRemoteCharacteristic->writeValue(xStr.c_str(), xStr.length()); xStr = "----------------------\r\n\r\n"; pRemoteCharacteristic->writeValue(xStr.c_str(), xStr.length()); } }else if(doScan) { BLEDevice::getScan()->start(0); // this is just example to start scan after disconnect, most likely there is better way to do it in arduino } delay(2); } } 总结

这个程序用Arduino 1.8.10编译通过。芯片采用了安信可的ESP32芯片。 在这里插入图片描述 程序的初始化在前面部分,for(;;)后面的程序是无线循环程序。当打印机连接时可以自动连接,当打印机断电再上电时可以自动连接。可以初步运行了。注意,在核0的程序最好需要增加延时,我增加了一个delay(2)的短延时,这也算是喂狗吧,没有这个延时会不断的重新启动。

程序的主要特点:

主程序在核1中执行。可以执行MCU需要时间紧迫处理的程序,比如我的程序是需要80ms时钟中断的仪表数据采集程序。蓝牙部分在核0中运行,速度慢不会影响到核1的数据采集。

需要进一步的工作: 1、如果是产品,更换打印机需要识别,并能够设置。 2、设置可以记忆。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3